package helper

import (
	"crypto/md5"
	"crypto/tls"
	"fmt"
	"github.com/golang-jwt/jwt/v4"
	"github.com/google/uuid"
	"github.com/jordan-wright/email"
	"math/rand"
	"net/smtp"
	"os"
	"time"
)

// 自定义的JWT生命结构体
type UserClaims struct {
	// 自定义字段
	Identity string `json:"identity"`
	Email    string `json:"email"`

	// 继承标准JWT声明
	jwt.RegisteredClaims
}

// GetMd5
// 生成 md5
func GetMd5(s string) string {
	return fmt.Sprintf("%x", md5.Sum([]byte(s)))
}

// 定义JWT密钥
var myKey = []byte("im")

// GenerateToken
// 生成 token
func GenerateToken(identity, email string) (string, error) {
	UserClaim := &UserClaims{
		Identity:         identity,
		Email:            email,
		RegisteredClaims: jwt.RegisteredClaims{},
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, UserClaim)
	tokenString, err := token.SignedString(myKey)
	if err != nil {
		return "", err
	}
	return tokenString, nil
}

// AnalyseToken
// 解析 token
func AnalyseToken(tokenString string) (*UserClaims, error) {
	userClaim := new(UserClaims)
	// 解析JWT
	claims, err := jwt.ParseWithClaims(tokenString, userClaim, func(token *jwt.Token) (interface{}, error) {
		// 确保JWT的签名方式是正确的
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
		}
		return myKey, nil
	})

	//处理错误信息
	if err != nil {
		return nil, err
	}

	// 可选：确认 claims 已正确解析
	if _, ok := claims.Claims.(*UserClaims); !ok {
		return nil, fmt.Errorf("invalid claims type")
	}
	return userClaim, nil
}

// GenerateCaptchaCode 生成验证码,
func GenerateCaptchaCode(length int) (string, error) {
	//创建局部随机数生成器
	source := rand.NewSource(time.Now().UnixNano())
	r := rand.New(source)
	result := make([]byte, length)
	for i := 0; i < length; i++ {
		result[i] = byte(r.Intn(10) + '0')
	}
	return string(result), nil
}

// SendCaptchaCode 发送验证码
func SendCaptchaCode(toUserEmail, captchaCode string) error {
	MailUser := os.Getenv("MAIL_USER")
	MailPassword := os.Getenv("MAIL_PASSWORD")
	e := email.NewEmail()
	e.From = "IM-system <" + MailUser + ">"
	e.To = []string{toUserEmail}
	e.Subject = "IM-system验证码，请查收！"
	e.HTML = []byte("您的验证码：<b>" + captchaCode + "</b>")
	err := e.SendWithTLS("smtp.163.com:587",
		smtp.PlainAuth("", MailUser, MailPassword, "smtp.163.com"),
		&tls.Config{InsecureSkipVerify: true, ServerName: "smtp.163.com"})
	return err
}

// GetUUID 生成唯一码
func GetUUID() string {
	newUUID, _ := uuid.NewV7()
	return newUUID.String()
}
